/************************************************************
 * Copyright (C), 2022-2030, ripnano. Co., Ltd.
 * FileName:        form_testing.h
 * Author:          Dan Yin
 * Date:            2024-07-16
 * Description:     the class of testing progress page
 * Version:         1.0.0.0
 **********************************************************/

#ifndef FORM_TESTING_H
#define FORM_TESTING_H

// add necessary includes here
#include "ui/defines/global.h"

class FormViewProcedure;
class FormProgressbar;
class MySwitchButton;

struct ST_STEP_INFO;

namespace Ui {
class FormTesting;
}

class FormTesting : public QWidget
{
    Q_OBJECT

public:
    typedef struct ST_STEP_COUNTDOWN {
        int nCmdId;
        int nTotalTime;

        ST_STEP_COUNTDOWN() {
            clear();
        }

        void clear() {
            nCmdId = 0;
            nTotalTime = 0;
        }
    }STEP_COUNTDOWN;

    // Get an instance of "FormTesting" class, if exist, return it
    static FormTesting* getInstance(QWidget *pParent = nullptr);

    // The default destructor
    virtual ~FormTesting();

signals:
    // The signal that refresh UI info
    void signalRefreshUI(bool bInit = true);

    // The signal that refresh procedure info on UI
    void signalRefreshProcedure();

    // Stop the testing mercilessly
    void signalStopTest();

    // Display experiment info
    void signalShowExperimentInfo();

    // Show the test details info by test ID
    void showShowPageResultDetails(int nTestId);

    // Draw hole position by painter
    int signalDrawHolePosition(int nAreaType, int nKitType, int nRowIdx, int nColFlags, QColor clrBrush);

private slots:
    void on_pushButton_SwitchTray_clicked();

    void on_pushButton_NewTest_clicked();

    void on_pushButton_Return_clicked();

     void on_pushButton_ViewProcedure_clicked();

     void on_pushButton_ResultInfo_clicked();

     void on_listView_Procedure_clicked(const QModelIndex &index);

     void on_listView_Procedure_2_clicked(const QModelIndex &index);

     // Switch the type of holes
     void on_tabWidget_KitType_currentChanged(int index);

    // The slot that refresh UI info
    void slotRefreshUI(bool bInit = true);

    // The slot that refresh procedure info on UI
    void slotRefreshProcedure();

    // Get the reply message from the child window
    void slotRespondInfoFromDlg(int nReplyType, bool bAccepted=true);

    // Get extract method info & PCR method info
    void slotRespondInfoFromDlg(int nReplyType, bool bAccepted, QVariant varProcessParams);

    // Show the extract cycles
    void slotProcessTestCycles(unsigned int unCanId, ST_FLOW_PROC_ACTION stFlowProcAction);

    // Receive a heat value on sample hole
    void slotHeatValueReceived(unsigned int unCanId, QList<float> lstDataValue);

    // Display the countdown
    void slotShowCountdown();

    // Draw hole position by painter
    int slotDrawHolePosition(int nAreaType, int nKitType, int nRowIdx, int nColFlags, QColor clrBrush = QColor());

    // Waiting for canceling testing
    void slotCancelTesting();

    // Read temperature timely
    void slotReadTemperature();

protected:
    // Triggers an event before it is switch language
    void changeEvent(QEvent *event);

private:
    // The default constructor
    FormTesting(QWidget *parent = nullptr);

    // After constructing object, initialize the object
    void _initialze();

    // Init the window style
    void _initUi();

    // Startup a testing
    int _startupTest();

    // Stop testing
    int _stopTest();

    // Complete testing
    void _completeTesting(bool bPCR);

    // Connect/disconnect signal-slots
    int _joinSignalSlotFuns(bool bConnect);

    // Split extract procedure action & push into queue
    int _splitProcedureAction(QQueue<ST_FLOW_PROC_ACTION> &queFlowProcAction, QList<ST_STEP_INFO> &lstModelData, int &nCycleCnt, const QString &sProcessContent);

    // Convert seconds to time
    QString _seconds2Time(int nSeconds);

    // Display the details of testing info
    void _refreshTestingInfoOnLabels(int nStatus);

    // Refresh the list view data
    void _refreshListView();

    // Load the images of testing status
    void _loadExtractImage(int nKitType = E_EK_T1C_HOLE_10);

    // Reset the images of testing status
    void _resetImages(int nKitType = E_EK_T1C_HOLE_10);

private:
    Ui::FormTesting *ui;

    FormViewProcedure       *m_pFrmViewProcedure = nullptr;
    FormProgressbar         *m_pFrmProgressbar = nullptr;

    QImage                  *m_pImageExtract = nullptr;
    QImage                  *m_pImageSample = nullptr;
    int                     m_nCurRowPosIdx = -1;
    int                     m_nSamplePosFlags = 0xff;

    mutable QMutex          m_mtxHeat;

    QTimer                  *m_pReadTemperature = nullptr;
    QTimer                  *m_pCancelTesting = nullptr;
    QTimer                  *m_pStepCountdown = nullptr;
    ST_STEP_COUNTDOWN       m_stStepCountdown;

    int                     m_nNewTestId = 0;
    int                     m_nExtractId = 0;
    QString                 m_sProcedureName = "";
    QDateTime               m_tTimeStamp;

    int                     m_nIapTesting = 0;
    int                     m_nFlowCycleCnt = 0;
    int                     m_nCurProcedureId = 0;
};

#endif // FORM_TESTING_H
